/* Project includes */
#include "main.h"
//#include "TSC_2046.h"
#include "Hal_InputManagement.h"
#include "Hal_OutputManagement.h"
#include "Hal_PwmManagement.h"
#include "Hal_UsartManagement.h"


#include "clock.h"

#ifdef _OSMOLATOR
    #include "osmolator.h"
#endif

#ifdef _TEMPERATURE
    #include "temperature.h"
#endif

#ifdef _LIGHT
    #include "light.h"
#endif

#ifdef _LEDSPWM
    #include "led.h"
#endif

#ifdef _OSCILLATOR
    #include "oscillator.h"
#endif

#ifdef _AFFICHAGE
    #include "affichage.h"
#endif

#ifdef _FAN
    #include "fan.h"
#endif

#ifdef _OUTPUT_LINES
    #include "output.h"
#endif

#ifdef _COMMAND
    #include "command.h"
#endif

/**
  * @brief  main(), contient tout les initialisations
  * @param  None
  * @retval : None
  */
int main()
{
    prvSetupHardware();     /* Initialisation du materiel. */

    message_queue = xQueueCreate( 20, sizeof(__MESSAGE) );
    if ( message_queue == NULL )
    {
        NVIC_SystemReset();
    }

#ifdef _OSCILLATOR
    oscillateur_queue = xQueueCreate( 2, sizeof(Oscillator_def_t) );
    if ( oscillateur_queue == NULL )
    {
        NVIC_SystemReset();
    }
#endif /* _OSCILLATOR */

#ifdef _LIGHT
    light_queue = xQueueCreate( 2, sizeof(Light_def_t) );
    if ( light_queue == NULL )
    {
        NVIC_SystemReset();
    }
#endif /* _LIGHT */

#ifdef _LEDSPWM
    led_queue = xQueueCreate( 3, sizeof(Led_def_t) );
    if ( led_queue == NULL )
    {
        NVIC_SystemReset();
    }
#endif /* _LEDSPWM */

    clock_queue = xQueueCreate( 2, sizeof(Clock_def_t) );
    if ( clock_queue == NULL )
    {
        NVIC_SystemReset();
    }

#ifdef _FAN
    fan_queue = xQueueCreate( 2, sizeof(Fan_def_t) );
    if ( fan_queue == NULL )
    {
        NVIC_SystemReset();
    }
#endif /* _FAN */

    xTaskCreate( (void*)vTaskInit, (void*)"init", configMINIMAL_STACK_SIZE+2048, NULL, tskIDLE_PRIORITY+4, NULL );

    /* Start the scheduler. */
    vTaskStartScheduler();

    /* Will only get here if there was not enough heap space to create the
    idle task. */
    while(1);

    return (0);
}

/*
 *  Initialisation du materiel
 */
void vTaskInit()
{
	/* init all abstraction module */
    vTaskCTRL_InputManagementInit();
    vTaskCTRL_OutputManagementInit();
    vTaskCTRL_PwmManagementInit();
    vTaskCTRL_UsartManagementInit();

    //TSC2046_Init();

    // initialisation de la sd card
    if ( SD_Config() != 0 )
    {
        printf("SDcard not present");
    }

    /* Start all application modules */
    xTaskCreate( (void*)vTaskCTRL, (void*)"CTRL", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+4, NULL);

    /* Then delete this task */
    vTaskDelete(NULL);
}
/*
 *  Demarrage du controleur general
 */
void vTaskCTRL()
{
    portTickType xLastWakeTime;

    xLastWakeTime = xTaskGetTickCount();

    // demarrage de tous les modules

    //
    // module horloge ( gestion heure, calendrier )
    //
    xTaskCreate( (void*)vTaskCTRL_TIME, (void*)"time", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_TIME);

    //
    // module command
    //
    #ifdef _COMMAND
        xTaskCreate( (void*)vTaskCTRL_COMMANDS, (void*)"command", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+4, &xHandle_Task_COMMAND);
    #endif

    //
    // module osmolator    ( gestion sonde niveau, pompe )
    //
    #ifdef _OSMOLATOR
        xTaskCreate( (void*)vTaskCTRL_OSMOLATOR, (void*)"osmolator", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSMOLATOR);
    #endif

    //
    // module temperature  ( gestion sonde, ventillateur, chauffage )
    //
    #ifdef _TEMPERATURE
        xTaskCreate( (void*)vTaskCTRL_TEMPERATURE, (void*)"temp", configMINIMAL_STACK_SIZE+512, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_TEMP);
    #endif

    //
    // module eclairage ( gestion eclairage )
    //
    #ifdef _LIGHT
          xTaskCreate( (void*)vTaskCTRL_ECLAIRAGE, (void*)"eclairage", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_LIGHT);
    #endif

    #ifdef _LEDSPWM
          xTaskCreate( (void*)vTaskCTRL_INTERPOLATED_LEDS_PWM, (void*)"LED", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_LEDSPWM);
    #endif

    //
    // module PHmetre ( gestion de la sonde PH )
    //
    #ifdef _PHMETRE

    #endif

    //
    // module oscilateur ( gestion de l'oscillation des pompes )
    //
    #ifdef _OSCILLATOR
        xTaskCreate( (void*)vTaskCTRL_OSCILLATOR, (void*)"oscillator", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSCILLATOR);
    #endif

    //
    // module ventilateur ( gestion des ventilateurs )
    //
    #ifdef _FAN
        xTaskCreate( (void*)vTaskCTRL_FAN, (void*)"fan", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_FANS);
    #endif

    //
    // module sortie standards
    //
    #ifdef _OUTPUT_LINES
        xTaskCreate( (void*)vTaskCTRL_OUTPUT_LINES, (void*)"output", configMINIMAL_STACK_SIZE+256, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OUTPUT_LINES);
    #endif

    //
    // module display
    //
    #ifdef _AFFICHAGE
        xTaskCreate( (void*)vTaskCTRL_AFFICHAGE, (void*)"affichage", configMINIMAL_STACK_SIZE+2048, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_AFFICHAGE);
    #endif

	/* Then delete this task */
	vTaskDelete(NULL);
}

/**
 * Manage stack overflow hook
 */
void vApplicationStackOverflowHook( xTaskHandle xTask,
                                    signed portCHAR *pcTaskName )
{
	printf("\r\n\r\nSTACK OVERFLOW ON TASK : %s", pcTaskName);
}

